%main = drawRing(main,pos,rings)
%   This function calculates the coordinates for a ring when one of it's
%   elements has been found to have cooridnates assigned to it. It does so
%   with the info from 'main' and 'rings', 'pos' is the position found to
%   have coordinates assigned to it.

%%
function main = drawRing(main,pos,rings)

%% Initialising
%The ringmarker we're working with is stored in 'num'. It however has first
%to be extracted from 'main' since multiple ringmarkers can be present at
%one poition.

%The correct ringmarker has not been found yet
found = false;
%Starting at count = 1, but increase is done in the start of the loop so
%first count is set to 0.
count = 0;
%For as long as the correct ringmarker has not been found,
while ~found
    %increase the count
    count = count+1;
    %and if the position the ringmarker should be found at is in a certain
    %ring and
    if sum([rings(count).elements] == pos)
        %not all elements in the ring are yet drawn
        if sum([main([rings(count).elements]).drawn]) < length(rings(count).elements)
            %the correct marker has been found:
            found = true;
        end
    end
end
%This marker is stored into 'num'.
num = count;

%The lenght of the ring is stored in 'n'
n = length(rings(num).elements);

%Drawn contains the first two ringelements that are already drawn, if there
%are more then they will drawn double since the ring can only be superposed
%over two elements.
drawn = rings(num).elements(find([main([rings(num).elements]).drawn]>=1,2,'last'));
drawn = sort(drawn);

%The angle needed for the rotation of the previous vector around [0 0]
angle = -360/n;
if length(drawn) == 2
    angle = -angle;
end

%% Main

%% Calculating base coordinates
%Predefining coor to speed up the forloop
coor = zeros(n,2);
%This forloop calculates the rotated [1 0] around [0 0] for the ring
%coordinates.
for j = 1:length(rings(num).elements)
    if j ~= 1
        coor(j,:) = coor(j-1,:)*[cosd(angle) -sind(angle);sind(angle)...
            cosd(angle)];
    else
        %The first vector has to have a length r that is equal to
        %s/2sin(pi/n) so that all the sides have length s.
        coor(j,:) = [1/(2*sin(pi/n)) 0]';
    end
end


%% Rotation around [0 0] of the whole ring
%If more than one element is already drawn,
if length(drawn) == 2
    %'one' Is the vector between the two already drawn ringelements.
    one = [main(drawn(2)).x-main(drawn(1)).x main(drawn(2)).y-main(drawn(1)).y];
    %'two' Is the vector between the first element that has already been
    %drawn and the element from 'main' that it is attached to.
    two = coor(find([rings(num).elements] == drawn(1)),:)-coor(n-find([rings(num).elements] == drawn(1))+1,:);
    %'tilt' Is the angle between 'one' and 'two'.
    tilt = acosd((two*one')/(norm(two)*norm(one)));
    %rotate around angle tilt plus the one time the angle in between the
    %corners of the ring.
    coor = [cosd(tilt+angle) -sind(tilt+angle);sind(tilt+angle) cosd(tilt+angle)]*coor';
    
else
    %If only one element has yet been drawn and it's not the first element
    %of the SMILES:
    if drawn ~= 1
        %'branchelements' Contains the elements of the branch to which the
        %drawn element belongs
        branchelements = find([main.branch] == main(drawn).branch);
        %If 'drawn' is the first element of this branch
        if drawn == branchelements(1)
            %Then the the one it's attached two is the element the branch
            %is attached to.
            prev = main(drawn).branchorigin;
        else
            %Else 'drawn' is attached to the element before it in the
            %branch.
            prev = branchelements(find(branchelements == drawn)-1);
        end
        %'vec1' Contains the coordinates from 'coor' that corrospond with
        %the element in 'drawn'.
        vec1 = coor([rings(num).elements] == drawn,:);
        %Is the ring has an even number of elements,
        if n/2 == round(n/2)
            %the opposite element is stored into 'oppnum'
            oppnum = find([rings(num).elements] == drawn)+n/2;
            %This if-statement correct the location might it be beyond the
            %end of the ring, since the opposite is expected to be n/2 away
            %in positive direction. If it actually is n/2 away in negative
            %direction, then this corrects it.
            if oppnum > n
                oppnum = oppnum -n;
            end
            %'vec2' Contains the coordinates for the opposite position.
            vec2 = coor(oppnum,:);
        else
            %If the ring has an uneven amount of elements:
            %The opposite position in the ring can be found between two
            %places, 'oppnum1' and 'oppnum2':
            %'oppnum1' Is calculated the same way as 'oppnum' is for even
            %membered rings, 'oppnum2' is the one before that.
            oppnum1 = find([rings(num).elements] == drawn)+round(n/2);
            oppnum2 = oppnum1 -1;
            %Ofcourse these two also have to be corrected when necessary.
            if oppnum1 > n
                oppnum1 = oppnum1-n;
            end
            %Since 'oppnum2' is one smaller than 'oppnum1' it needs a
            %seperate check:
            if oppnum2 > n
                oppnum2 = oppnum2-n;
            end
            %The second vector is the location in between the two opposite
            %positions.
            vec2 = .5*(coor(oppnum1,:)-coor(oppnum2,:))+coor(oppnum2,:);
        end
        one = vec1-vec2;
        two = [main(drawn).x main(drawn).y]-[main(prev).x main(prev).y];
        tilt = real(acosd((two*one')/(norm(two)*norm(one)))+180);
        coor = [cosd(tilt) -sind(tilt);sind(tilt) cosd(tilt)]*coor';
    else
        %If the drawn position is the first element of the SMILES,
        %transpose 'coor' for further use like the rotations would have.
        coor = coor';
    end
end

%Translation upon the known elements
coor(1,:) = coor(1,:) + (main(drawn(1)).x-coor(1,1));
coor(2,:) = coor(2,:) + (main(drawn(1)).y-coor(2,1));

%% Storing the coordinates in main
%And setting the elements' drawn label to 1.
for j = 1:n
    main(rings(num).elements(j)).x = coor(1,j);
    main(rings(num).elements(j)).y = coor(2,j);
    main(rings(num).elements(j)).drawn = 1;
end

%% End
end